package com.lokiy.kit.widget

import android.content.Context
import android.content.res.TypedArray
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.RectF
import android.util.AttributeSet
import android.widget.FrameLayout
import com.lokiy.kit.R
import com.lokiy.kit.ext.dp

/**
 * 圆角控件
 * @author Lokiy
 * @date 2023-08-21 14:48
 */
class CornerLayout(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs) {

    private val xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_IN)
    private val rectf = RectF()
    private val path = Path()
    var topLeftRadius = 0f
        set(value) {
            field = check(topRightRadius, bottomLeftRadius, value)
            invalidate()
        }
    var topRightRadius = 0f
        set(value) {
            field = check(topLeftRadius, bottomRightRadius, value)
            invalidate()
        }
    var bottomLeftRadius = 0f
        set(value) {
            field = check(bottomRightRadius, topLeftRadius, value)
            invalidate()
        }
    var bottomRightRadius = 0f
        set(value) {
            field = check(bottomLeftRadius, topRightRadius, value)
            invalidate()
        }

    private val paint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.FILL_AND_STROKE
        strokeWidth = 1f
        color = 0xFF00FF00.toInt()
    }

    init {
        val a: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.CornerLayout)
        val radius = a.getDimension(R.styleable.CornerLayout_android_radius, 0f)
        if (radius > 0f) {
            topLeftRadius = radius
            topRightRadius = radius
            bottomRightRadius = radius
            bottomLeftRadius = radius
        } else {
            topLeftRadius = a.getDimension(R.styleable.CornerLayout_android_topLeftRadius, 0f)
            topRightRadius = a.getDimension(R.styleable.CornerLayout_android_topRightRadius, 0f)
            bottomLeftRadius = a.getDimension(R.styleable.CornerLayout_android_bottomLeftRadius, 0f)
            bottomRightRadius = a.getDimension(R.styleable.CornerLayout_android_bottomRightRadius, 0f)
        }
        a.recycle()
    }

    private fun check(width1: Float, height1: Float, value: Float) = if (width > 0) {
        val max = (width - width1).coerceAtMost(height - height1)
        value.coerceAtMost(max)
    } else {
        value
    }

    override fun dispatchDraw(canvas: Canvas?) {
        canvas ?: return
        rectf.set(0f, 0f, width.toFloat(), height.toFloat())


        val canvasWidth = canvas.width.toFloat()
        val canvasHeight = canvas.height.toFloat()
        val layerId = canvas.saveLayer(0f, 0f, canvasWidth, canvasHeight, null)

        super.dispatchDraw(canvas)

        val bitmap = Bitmap.createBitmap(canvas.width, canvas.height, Bitmap.Config.ARGB_8888)
        val cv = Canvas(bitmap)
        path.reset()
        path.addRoundRect(
            rectf, floatArrayOf(
                topLeftRadius, topLeftRadius,
                topRightRadius, topRightRadius,
                bottomRightRadius, bottomRightRadius,
                bottomLeftRadius, bottomLeftRadius,
            ),
            Path.Direction.CCW
        )

        cv.drawPath(path, paint)

        paint.xfermode = xfermode
        canvas.drawBitmap(bitmap, 0f, 0f, paint)
        paint.xfermode = null

        canvas.restoreToCount(layerId)
    }
}